using System;
using System.Text;

namespace Pretorianie.Sangraal.Providers.Data
{
    /// <summary>
    /// This class recognizes the most common type of files.
    /// </summary>
    internal class CommonFolderAttributeProvider : IFolderAttributesDescriptor
    {
        private static string[] Sizes = new string[] { " bytes", " KB", " MB", " GB", " TB" };
        private readonly ItemAttributes folderAttributes;
        private readonly ItemAttributes fileNone;
        private readonly ItemAttributes fileAspx;
        private readonly ItemAttributes fileAscx;
        private readonly ItemAttributes fileCS;
        private readonly ItemAttributes fileCSS;
        private readonly ItemAttributes fileConfig;
        private readonly ItemAttributes fileTxt;
        private readonly ItemAttributes fileVB;
        private readonly ItemAttributes fileXML;

        public CommonFolderAttributeProvider()
        {
            folderAttributes = new ItemAttributes("folder.gif", "File Folder");
            fileNone = new ItemAttributes("empty.gif", "Unknown File Format");
            fileAspx = new ItemAttributes("aspx.gif", "ASP.NET Server Page");
            fileAscx = new ItemAttributes("ascx.gif", "ASP.NET User Control");
            fileCS = new ItemAttributes("cs.gif", "C# File");
            fileCSS = new ItemAttributes("css.gif", "CSS Document");
            fileConfig = new ItemAttributes("config.gif", "Web Config File");
            fileTxt = new ItemAttributes("text.gif", "Text File");
            fileVB = new ItemAttributes("vb.gif", "VB.NET File");
            fileXML = new ItemAttributes("xml.gif", "XML File");
        }

        #region Implementation of IFolderAttributesDescriptor

        /// <summary>
        /// Provide folder generic description based on name.
        /// </summary>
        public ItemAttributes GetFolderAttributes(string name)
        {
            return folderAttributes;
        }

        /// <summary>
        /// Provide file generic description based on name or extension.
        /// </summary>
        public ItemAttributes GetFileAttributes(string name, string extensionOnly)
        {
            switch (extensionOnly)
            {
                case "":
                    return fileNone;
                case ".txt":
                    return fileTxt;
                case ".aspx":
                    return fileAspx;
                case ".ascx":
                    return fileAscx;
                case ".cs":
                    return fileCS;
                case ".vb":
                    return fileVB;
                case ".config":
                    return fileConfig;
                case ".xml":
                    return fileXML;
                case ".css":
                    return fileCSS;
                case ".exe":
                    return new ItemAttributes("exe.gif", "Application Executable");
                case ".dll":
                    return new ItemAttributes("dll.gif", "Application Extension");
                case ".js":
                    return new ItemAttributes("js.gif", "JavaScript File");
                case ".gif":
                    return new ItemAttributes("image.gif", "GIF Image File");
                case ".jpg":
                    return new ItemAttributes("image.gif", "JPEG Image File");
                case ".png":
                    return new ItemAttributes("image.gif", "PNG Image File");
                default:
                    return new ItemAttributes("file.gif", extensionOnly.Replace(".", "").ToUpper() + " File");
            }
        }

        /// <summary>
        /// Format file size into string.
        /// </summary>
        public string GetFormattedSize(long size)
        {
            StringBuilder result = new StringBuilder();
            
            foreach (string s in Sizes)
            {
                if(size < 1024)
                {
                    result.Append(size).Append(s);
                    break;
                }

                size = (size + 1023)/1024;
            }

            return result.ToString();
        }

        /// <summary>
        /// Format any date (last write time/ creation date/ last access time into string.
        /// </summary>
        public string GetFormattedDate(DateTime dt)
        {
            return dt.ToString("dd/MM/yyyy hh:mm tt");
        }

        #endregion
    }
}